import { GameObject } from "./GameObject";
import { Cell } from "./Cell";
export class Snake extends GameObject{
    constructor(info, gameMap){
        super();
        this.id=info.id;
        this.color=info.color;
        this.gameMap=gameMap;
        this.cells=[new Cell(info.r,info.c)] //存放蛇的身体，初始cells[0] 为蛇头
        this.speed=5;//蛇每秒走多少个格子
        this.direction =-1; //-1表示没有指令，0 1 2 3 表示上右下左
        this.status="idle";//idle表示静止 move 表示正在移动 die 表示死亡
        this.dr=[-1, 0, 1, 0];//四个方向的行偏移量
        this.dc=[0,1,0,-1];//四个方向的列偏移量
        this.step=0;//表示回合数 蛇的增长与回合有关
        this.eps = 1e-2;//允许的误差
        //初始化蛇的眼睛
        if(this.id == 0) this.eyeDirection = 0;//左上角蛇眼初始化朝上
        if(this.id == 1) this.eyeDirection = 2;//右下角蛇眼初始化朝下
        this.eyeDx=[ //蛇眼睛在x轴不同方向的偏移量
        [-1,1],
        [1,1],
        [1,-1],
        [-1,-1]
        ];
        this.eyeDy=[ //蛇眼睛在y轴不同方向的偏移量
        [-1,-1],
        [-1,1],
        [1,1],
        [1,-1]
        ];
    }
    start(){

    }
    setDirection( direction){
        this.direction=direction;
    }
    //检测当前回合 蛇的长度是否增加
    checkTailIncreasing(){
        if(this.step<=10) return true;
        if(this.step%3 === 1) return true;
        return false;
    }
    nextStep(){ //将蛇的状态变为走下一步
        const d =this.direction;
        this.nextCell=new Cell(this.cells[0].r+this.dr[d],this.cells[0].c+this.dc[d]);
        this.eyeDirection=d;//更新蛇的眼睛
        this.direction=-1;//清空操作
        this.status="move";
        this.step++;
        const k=this.cells.length;
        for(let i=k;i>0;i--){
            this.cells[i]=JSON.parse(JSON.stringify(this.cells[i-1]));
        }
        //结果判断改在后端
        // //如果下一步撞墙了，蛇瞬间去世 
        // if(!this.gameMap.checkValid(this.nextCell)){
        //     this.status="die";
        // }
    }
    updateMove(){
        // //根据速度，得出每帧移动多少步=速度*时间（换算成second）
        // this.cells[0].x+=this.speed*this.timedelta/1000;
        //考虑一种一般情况，即目标与蛇头位置任意
        const dx=this.nextCell.x-this.cells[0].x;
        const dy=this.nextCell.y-this.cells[0].y;
        const distance=Math.sqrt(dx*dy,dy*dy);
        if(distance<this.eps){
            this.cells[0]=this.nextCell;//添加一个新蛇头
            this.nextCell=null;
            this.status="idle";//走完了停下来
            if(!this.checkTailIncreasing()){
                this.cells.pop();//如果蛇不变长 且已经移动过来了 就把蛇尾砍掉
            }
        }else{
            //根据速度，得出每帧移动多少步=速度*时间（换算成second）
            const moveDistance=this.speed*this.timedelta/1000;
            this.cells[0].x+=moveDistance*dx/distance;//x=d*cosa
            this.cells[0].y+=moveDistance*dy/distance;//x=d*sina
            if(this.checkTailIncreasing()){ //如果蛇不变长
                const k= this.cells.length;
                //蛇尾 和 蛇尾的目标位置
                const tail= this.cells[k-1]
                const tailTarget=this.cells[k-2];
                const tailDx=tailTarget.x-tail.x;
                const tailDy=tailTarget.y-tail.y;
                tail.x+=moveDistance*tailDx/distance;
                tail.y+=moveDistance*tailDy/distance;

            }
        }
    }
    //每帧执行一次
    update(){
        if(this.status ==='move'){
            console.log("move");
            //每帧都要移动直到距离小于误差
            this.updateMove();
        }
        this.render();
    }
    render(){
        const L=this.gameMap.L;
        const ctx=this.gameMap.ctx;
        ctx.fillStyle=this.color;
        //如果蛇死了，就画成白色
        if(this.status==='die'){
            ctx.fillStyle="white";
        }
        for(const cell of this.cells){
            ctx.beginPath();
            ctx.arc(cell.x*L,cell.y*L,L/2*0.8,0,Math.PI*2);//圆心坐标 半径 起始点角度
            ctx.fill();
        }
        for(let i=1;i<this.cells.length;i++){
            const a=this.cells[i-1];
            const b=this.cells[i];
            if(Math.abs(a.x-b.x)<this.eps&&Math.abs(a.y-b.y)<this.eps){
                continue;
            }
            if(Math.abs(a.x-b.x)<this.eps){
                ctx.fillRect((a.x-0.4)*L,Math.min(a.y,b.y)*L,L*0.8,Math.abs(a.y-b.y)*L);
            }else{
                ctx.fillRect(Math.min(a.x,b.x)*L,(a.y-0.4)*L,Math.abs(a.x-b.x)*L,L*0.8);
            }
        }
        ctx.fillStyle="black";
        //i表示从0到1表示两个眼睛
        for(let i=0;i<2;i++){
            const eyeX=(this.cells[0].x+this.eyeDx[this.eyeDirection][i]*0.15)*L;
            const eyeY=(this.cells[0].y+this.eyeDy[this.eyeDirection][i]*0.15)*L;  
            ctx.beginPath();
            ctx.arc(eyeX,eyeY,L*0.05,0,Math.PI*2);
            ctx.fill(); 
        }
    }
}

